package com.chuangmei.com.map;

import android.graphics.Color;
import android.location.Location;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.Poi;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.baidu.mapapi.search.route.BikingRouteResult;
import com.baidu.mapapi.search.route.DrivingRouteLine;
import com.baidu.mapapi.search.route.DrivingRoutePlanOption;
import com.baidu.mapapi.search.route.DrivingRouteResult;
import com.baidu.mapapi.search.route.IndoorRouteResult;
import com.baidu.mapapi.search.route.MassTransitRouteResult;
import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener;
import com.baidu.mapapi.search.route.PlanNode;
import com.baidu.mapapi.search.route.RoutePlanSearch;
import com.baidu.mapapi.search.route.TransitRouteResult;
import com.baidu.mapapi.search.route.WalkingRouteResult;
import com.baidu.trace.LBSTraceClient;
import com.baidu.trace.Trace;
import com.baidu.trace.api.track.HistoryTrackRequest;
import com.baidu.trace.api.track.HistoryTrackResponse;
import com.baidu.trace.api.track.OnTrackListener;
import com.baidu.trace.model.OnTraceListener;
import com.baidu.trace.model.PushMessage;
import com.chuangmei.com.BaseActivity;
import com.chuangmei.com.R;
import com.chuangmei.com.overlayutil.DrivingRouteOverlay;

import java.util.ArrayList;
import java.util.List;

public class MapActivity extends BaseActivity implements View.OnClickListener {


    private MapView mMapView;
    private Button mBT_map_return;
    private LocationClient mLocationClient;
    private BaiduMap mBaiduMap;
    private Button mBT_location;
    private BitmapDescriptor locationBitmap;
    private BDLocation realTimeLocation;
    private boolean flag = true;
    private String Tag = "luohao";
    private MyOrientationListener myOrientationListener;
    private TextView mTV_address;
    private Button mBT_path_planning;


    @Override
    public void initEnvironment() {
        //在使用SDK各组件之前初始化context信息，传入ApplicationContext
        //注意该方法要再setContentView方法之前实现
        SDKInitializer.initialize(getApplicationContext());
    }

    @Override
    public void initActivityLayoutID() {
        activityLayoutID = R.layout.activity_map;
    }

    @Override
    public void initView() {
        //获取地图控件引用
        mMapView = (MapView) this.findViewById(R.id.mMV);
        mTV_address = (TextView) this.findViewById(R.id.mTV_address);
        mBT_map_return = (Button) this.findViewById(R.id.mBT_map_return);
        mBT_path_planning = (Button) this.findViewById(R.id.mBT_path_planning);
        mBT_location = (Button) this.findViewById(R.id.mBT_location);
        mBT_map_return.setOnClickListener(this);
        mBT_path_planning.setOnClickListener(this);
        mBT_location.setOnClickListener(this);
    }

    @Override
    public void initData() {
        mBaiduMap = mMapView.getMap();

        mBaiduMap.setBaiduHeatMapEnabled(false);//热力图
        mBaiduMap.setIndoorEnable(true);//打开室内图，默认为关闭状态
        mBaiduMap.setTrafficEnabled(true);  //开启交通图
        mBaiduMap.setCustomTrafficColor("#ffba0101", "#fff33131", "#ffff9e19", "#00000000");
        // 设置是否显示缩放控件
        mMapView.showZoomControls(true);
        // 设置是否显示定位按钮
        // 删除百度地图LoGo
        mMapView.removeViewAt(1);

        MapStatusUpdate u = MapStatusUpdateFactory.zoomTo(13);
        mBaiduMap.animateMapStatus(u);
        // 设置marker图标
        locationBitmap = BitmapDescriptorFactory
                .fromResource(R.drawable.click_location);
        startLocate();
        initTouchLocate();
    }

    /**
     * 触摸点数据
     */
    private void initTouchLocate() {
        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
            // 此方法就是点击地图监听
            @Override
            public void onMapClick(LatLng latLng) {
                //获取触摸点的经纬度
                double longitude = latLng.longitude;
                double latitude = latLng.latitude;
                //先清除图层
                mBaiduMap.clear();
                //定义maker坐标点
                LatLng point = new LatLng(latitude, longitude);
                // 构建MarkerOption，用于在地图上添加Marker
                MarkerOptions options = new MarkerOptions().position(point)
                        .icon(locationBitmap);
                // 在地图上添加Marker，并显示
                mBaiduMap.addOverlay(options);
                // 实例化一个地理编码查询对象
                GeoCoder geoCoder = GeoCoder.newInstance();
                // 设置反地理编码位置坐标
                ReverseGeoCodeOption op = new ReverseGeoCodeOption();
                op.location(latLng);
                // mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(latLng));
                // 发起反地理编码请求(经纬度->地址信息)
                geoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
                    @Override
                    public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {

                    }

                    @Override
                    public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
                        LatLng location = reverseGeoCodeResult.getLocation();
                        String address = reverseGeoCodeResult.getAddress();
                        String city = reverseGeoCodeResult.getAddressDetail().city;
                        StringBuffer stringBuffer = new StringBuffer();

                        stringBuffer.append("地址：" + address);
                        //stringBuffer.append("---" + location.toString());
                        mTV_address.setText(stringBuffer.toString());
                    }
                });
                //开启反地理编码
                geoCoder.reverseGeoCode(op);
            }

            @Override
            public boolean onMapPoiClick(MapPoi mapPoi) {
                return false;
            }
        });
    }

    /**
     * 定位
     */
    private void startLocate() {
        mLocationClient = new LocationClient(getApplicationContext());     //声明LocationClient类
        mLocationClient.registerLocationListener(new MyLocationListener());    //注册监听函数
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving
        );//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        option.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系
        int span = 1000;
        option.setScanSpan(span);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
        option.setOpenGps(true);//可选，默认false,设置是否使用gps
        option.setLocationNotify(true);//可选，默认false，设置是否当GPS有效时按照1S/1次频率输出GPS结果
        option.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation
        // .getLocationDescribe里得到，结果类似于“在钟楼附近”
        option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
        option.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        option.setEnableSimulateGps(false);//可选，默认false，设置是否需要过滤GPS仿真结果，默认需要
        mLocationClient.setLocOption(option);
        //开启定位
        mLocationClient.start();
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);

    }

    private class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {

            StringBuffer sb = new StringBuffer(256);
            sb.append("time : ");
            sb.append(location.getTime());
            sb.append("\nerror code : ");
            sb.append(location.getLocType());
            sb.append("\nlatitude : ");
            sb.append(location.getLatitude());
            sb.append("\nlontitude : ");
            sb.append(location.getLongitude());
            sb.append("\nradius : ");
            sb.append(location.getRadius());
            if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
                sb.append("\nspeed : ");
                sb.append(location.getSpeed());// 单位：公里每小时
                sb.append("\nsatellite : ");
                sb.append(location.getSatelliteNumber());
                sb.append("\nheight : ");
                sb.append(location.getAltitude());// 单位：米
                sb.append("\ndirection : ");
                sb.append(location.getDirection());// 单位度
                sb.append("\naddr : ");
                sb.append(location.getAddrStr());
                sb.append("\ndescribe : ");
                sb.append("gps定位成功");

            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
                sb.append("\naddr : ");
                sb.append(location.getAddrStr());
                //运营商信息
                sb.append("\noperationers : ");
                sb.append(location.getOperators());
                sb.append("\ndescribe : ");
                sb.append("网络定位成功");
            } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
                sb.append("\ndescribe : ");
                sb.append("离线定位成功，离线定位结果也是有效的");
            } else if (location.getLocType() == BDLocation.TypeServerError) {
                sb.append("\ndescribe : ");
                sb.append("服务端网络定位失败，可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com，会有人追查原因");
            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                sb.append("\ndescribe : ");
                sb.append("网络不同导致定位失败，请检查网络是否通畅");
            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                sb.append("\ndescribe : ");
                sb.append("无法获取有效定位依据导致定位失败，一般是由于手机的原因，处于飞行模式下一般会造成这种结果，可以试着重启手机");
            }
            sb.append("\nlocationdescribe : ");
            sb.append(location.getLocationDescribe());// 位置语义化信息
            List<Poi> list = location.getPoiList();// POI数据
            if (list != null) {
                sb.append("\npoilist size = : ");
                sb.append(list.size());
                for (Poi p : list) {
                    sb.append("\npoi= : ");
                    sb.append(p.getId() + " " + p.getName() + " " + p.getRank());
                }
            }
            Log.i("描述：", sb.toString());
            // 定位成功后就停止
            //            mBaiduMap.setMyLocationEnabled(false);
            //            if (mLocationClient.isStarted()) {
            //                mLocationClient.stop();
            //            }
            realTimeLocation = location;

            if (flag) {
                LatLng latLng = new LatLng(location.getLatitude(),
                        location.getLongitude());
                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(latLng));
            }
            location = null;
            // 当不需要定位图层时关闭定位图层
            //            mBaiduMap.setMyLocationEnabled(false);
            if (flag) {
                initOritationListener();
                flag = false;
            }
        }

    }

    /**
     * 初始化方向传感器
     */
    private void initOritationListener() {
        myOrientationListener = new MyOrientationListener(
                getApplicationContext());
        myOrientationListener.setOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
            @Override
            public void onOrientationChanged(float x) {

                int mXDirection = (int) x;
                Log.i(Tag, "onOrientationChanged: " + x);
                MyLocationData locData = new MyLocationData.Builder()
                        .accuracy(realTimeLocation.getRadius())
                        // 此处设置开发者获取到的方向信息，顺时针0-360
                        .direction(mXDirection).latitude(realTimeLocation.getLatitude())
                        .longitude(realTimeLocation.getLongitude()).build();

                // 设置定位数据
                mBaiduMap.setMyLocationData(locData);

                // 设置定位图层的配置（定位模式，是否允许方向信息，用户自定义定位图标）
                //                BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory
                //                        .fromResource(R.drawable.direction);
                MyLocationConfiguration config = new MyLocationConfiguration(MyLocationConfiguration.LocationMode
                        .NORMAL,
                        true, null);
                // 定位信息 传输进去 比例尺传输进去
                mBaiduMap.setMyLocationConfiguration(config);
            }
        });
        myOrientationListener.start();
    }


    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume ()，实现地图生命周期管理
        mMapView.onResume();

    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView. onPause ()，实现地图生命周期管理
        mMapView.onPause();

    }

    @Override
    protected void onStop() {
        super.onStop();
        //在activity执行onDestroy时执行mMapView.onDestroy()，实现地图生命周期管理
        mMapView.onDestroy();

        if (myOrientationListener != null) {
            myOrientationListener.stop();
            myOrientationListener = null;
        }


        if (mSearch != null)
            mSearch.destroy();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.mBT_map_return:
                finish();
                break;
            case R.id.mBT_path_planning:
                routeSearch();
                break;
            case R.id.mBT_location:
                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(new LatLng(realTimeLocation.getLatitude(),
                        realTimeLocation.getLongitude())));
                break;
            default:
                break;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                return true;
            default:
                break;
        }
        return super.onKeyDown(keyCode, event);

    }


    //    double mLat1 = 39.915291;
    //    double mLon1 = 116.403857;
    //    double mLat2 = 40.056858;
    //    double mLon2 = 116.308194;
    //    LatLng startPt = new LatLng(mLat1, mLon1);
    //    LatLng endPt = new LatLng(mLat2, mLon2);
    private RoutePlanSearch mSearch;

    private void routeSearch() {
        if (realTimeLocation != null) {
            mSearch = RoutePlanSearch.newInstance();
            mSearch.setOnGetRoutePlanResultListener(geoCoderResultListener);
            mSearch.drivingSearch((new DrivingRoutePlanOption()).from(PlanNode.withLocation(new LatLng
                    (realTimeLocation.getLatitude(), realTimeLocation.getLongitude()))).to(PlanNode
                    .withCityNameAndPlaceName("咸阳",
                            "陕西工业职业技术学院")));
        } else {
            Toast.makeText(this, "未得到定位数据，请稍后...", Toast.LENGTH_LONG).show();
        }
    }


    private DrivingRouteLine route;
    OnGetRoutePlanResultListener geoCoderResultListener = new OnGetRoutePlanResultListener() {


        @Override
        public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {

        }

        @Override
        public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {

        }

        @Override
        public void onGetMassTransitRouteResult(MassTransitRouteResult massTransitRouteResult) {

        }

        @Override
        public void onGetDrivingRouteResult(DrivingRouteResult result) {
            //TODO: 在地图上绘制驾车路线
            if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
                //起终点或途经点地址有岐义，通过以下接口获取建议查询信息
                //result.getSuggestAddrInfo()
                Log.d("baiduMap", "起终点或途经点地址有岐义");
                return;
            }
            if (result.error == SearchResult.ERRORNO.PERMISSION_UNFINISHED) {
                //权限鉴定未完成则再次尝试
                Log.d("baiduMap", "权限鉴定未完成,再次尝试");
                return;
            }
            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
                Toast.makeText(MapActivity.this, "抱歉，未找到结果", Toast.LENGTH_SHORT).show();
                return;
            }
            if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
                //起终点或途经点地址有岐义，通过以下接口获取建议查询信息
                result.getSuggestAddrInfo();
                return;
            }
            //路线查询成功
            if (result.error == SearchResult.ERRORNO.NO_ERROR) {
                route = result.getRouteLines().get(0);
                DrivingRouteOverlay overlay = new MyDrivingRouteOverlay(mBaiduMap);

                //routeOverlay = overlay;
                mBaiduMap.setOnMarkerClickListener(overlay);
                overlay.setData(result.getRouteLines().get(0));
                overlay.addToMap();
                overlay.zoomToSpan();
            }

        }

        @Override
        public void onGetIndoorRouteResult(IndoorRouteResult indoorRouteResult) {

        }

        @Override
        public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {

        }
    };
    //定制RouteOverly

    /**
     * DrivingRouteOverlay已经实现了BaiduMap.OnMarkerClickListener接口
     */
    private class MyDrivingRouteOverlay extends DrivingRouteOverlay {

        public MyDrivingRouteOverlay(BaiduMap baiduMap) {

            super(baiduMap);
        }

        @Override
        public int getLineColor() {
            //红色的路径
            return Color.RED;
        }

        @Override
        public BitmapDescriptor getStartMarker() {
            //            if (useDefaultIcon) {
            return BitmapDescriptorFactory.fromResource(R.drawable.direction);
            //            }
            //            return null;
        }

        @Override
        public BitmapDescriptor getTerminalMarker() {
            return BitmapDescriptorFactory.fromResource(R.drawable.app_icon);
        }
    }
}
